package com.nineclock.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nineclock.attendance.dto.DepartmentOrUserSimpleDTO;
import com.nineclock.attendance.enums.AttendEnums;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.common.utils.CurrentUserHolder;
import com.nineclock.system.dto.SysDepartmentDTO;
import com.nineclock.system.mapper.SysCompanyUserMapper;
import com.nineclock.system.mapper.SysDepartmentMapper;
import com.nineclock.system.pojo.SysCompanyUser;
import com.nineclock.system.pojo.SysDepartment;
import com.nineclock.system.service.SysCompanyUserService;
import com.nineclock.system.service.SysDepartmentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Wrapper;
import java.util.ArrayList;
import java.util.List;

@Service
public class SysDepartmentServiceImpl extends ServiceImpl<SysDepartmentMapper, SysDepartment> implements SysDepartmentService {
    @Override
    public List<Long> departmentIdList(List<Long> departmentIdList, Long id) {
        //获取公司ID
        Long companyId = CurrentUserHolder.get().getCompanyId();

        List<SysDepartment> deptList = this.list(Wrappers.<SysDepartment>lambdaQuery()
                .eq(SysDepartment::getCompanyId, companyId)
                .eq(SysDepartment::getParentId, id));

        //2.如果列表为空直接返回
        if (CollectionUtil.isEmpty(deptList)) {
            return new ArrayList<Long>();
        }

        //4.遍历部门列表，根据公司ID和本部门ID作为父ID，查询部门列表，递归执行
        for (SysDepartment sysDepartment : deptList) {
            Long departmentId = sysDepartment.getId();
            departmentIdList.add(departmentId);

            departmentIdList(departmentIdList, departmentId);
        }
        return departmentIdList;
    }

    @Override
    public List<SysDepartmentDTO> findDeptList() {

        //获取公司ID
        Long companyId = CurrentUserHolder.get().getCompanyId();
        //顶级部门ID
        Long parentId = 0l;
        //遍历获取每一级部门列表
        List<SysDepartmentDTO> list = findDeptList(companyId, parentId);
        return list;
    }

    /**
     * 递归查询每一级的部门列表
     *
     * @param companyId
     * @param parentId
     * @return
     */
    public List<SysDepartmentDTO> findDeptList(Long companyId, Long parentId) {


        //1.根据公司ID和父部门ID查询部门列表
        List<SysDepartment> deptList = this.list(Wrappers.<SysDepartment>lambdaQuery().eq(SysDepartment::getCompanyId, companyId).eq(SysDepartment::getParentId, parentId));

        //2.如果列表为空直接返回
        if (CollectionUtil.isEmpty(deptList)) {
            return new ArrayList<SysDepartmentDTO>();
        }
        //3.复制数据为DTO
        List<SysDepartmentDTO> sysDeptDtoList = BeanHelper.copyWithCollection(deptList, SysDepartmentDTO.class);
        //4.遍历部门列表，根据公司ID和本部门ID作为父ID，查询部门列表，递归执行
        sysDeptDtoList.forEach(dept -> {
            List<SysDepartmentDTO> childDeptList = findDeptList(companyId, dept.getId());
            dept.setChildren(childDeptList);
        });
        return sysDeptDtoList;
    }


    @Override
    public List<SysDepartment> findAllDept() {

        //获取公司ID
        Long companyId = CurrentUserHolder.get().getCompanyId();

        //遍历获取所有部门列表
        List<SysDepartment> list = this.list(Wrappers.<SysDepartment>lambdaQuery()
                .eq(SysDepartment::getCompanyId, companyId));

        return list;
    }

    @Autowired
    private SysCompanyUserMapper sysCompanyUserMapper;

    @Override
    public List<DepartmentOrUserSimpleDTO> findDeptListByParentId(Long id) {
        UserInfo userInfo = CurrentUserHolder.get();
        if (userInfo == null) {
            throw new NcException(ResponseEnum.USER_NOT_FOUND);
        }

        //获取公司ID
        Long companyId = userInfo.getCompanyId();

        List<SysDepartment> sysDepartmentList = this.list(Wrappers.<SysDepartment>lambdaQuery()
                .eq(SysDepartment::getParentId, id));

        List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOList = new ArrayList<>();
        //能查到下属部门就返回下属部门
        if (sysDepartmentList != null && sysDepartmentList.size() > 0) {
            getSimpleDTOList4Department(sysDepartmentList, departmentOrUserSimpleDTOList);

            //没有下属部门就返回部门员工
        } else {
            getSimpleDTOList4User(id, departmentOrUserSimpleDTOList);
        }
        return departmentOrUserSimpleDTOList;
    }

    private void getSimpleDTOList4User(Long id, List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOList) {
        List<SysCompanyUser> sysCompanyUserList = sysCompanyUserMapper.selectList(Wrappers.<SysCompanyUser>lambdaQuery()
                .eq(SysCompanyUser::getDepartmentId, id));

        if (sysCompanyUserList == null || sysCompanyUserList.size() == 0) {
            DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
            departmentOrUserSimpleDTOList.add(departmentOrUserSimpleDTO);
        } else {
            for (SysCompanyUser sysCompanyUser : sysCompanyUserList) {
                DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
                departmentOrUserSimpleDTO.setId(sysCompanyUser.getId());
                departmentOrUserSimpleDTO.setName(sysCompanyUser.getUserName());
                departmentOrUserSimpleDTO.setType(AttendEnums.ATTEND_OBJECT_TYPE_USER.value());

                departmentOrUserSimpleDTOList.add(departmentOrUserSimpleDTO);
            }
        }
    }

    private void getSimpleDTOList4Department(List<SysDepartment> sysDepartmentList, List<DepartmentOrUserSimpleDTO> departmentOrUserSimpleDTOList) {
        for (SysDepartment sysDepartment : sysDepartmentList) {
            DepartmentOrUserSimpleDTO departmentOrUserSimpleDTO = new DepartmentOrUserSimpleDTO();
            departmentOrUserSimpleDTO.setId(sysDepartment.getId());
            departmentOrUserSimpleDTO.setName(sysDepartment.getName());
            departmentOrUserSimpleDTO.setType(AttendEnums.ATTEND_OBJECT_TYPE_DEP.value());

            departmentOrUserSimpleDTOList.add(departmentOrUserSimpleDTO);
        }
    }
}
